package com.gitee.ed.structure.map;

import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.function.BiFunction;
import java.util.function.Function;

/**
 * 忽略大小写的 StringMap 结构
 *
 * @author hongda.li
 */
public class CaseInsensitiveMap<V> extends StringMap<V> {

    @Override
    public V put(String key, V value) {
        Objects.requireNonNull(key);
        return super.put(key.toLowerCase(Locale.ROOT), value);
    }

    @Override
    public void putAll(Map<? extends String, ? extends V> otherMap) {
        Objects.requireNonNull(otherMap);
        otherMap.forEach(this::put);
    }

    @Override
    public V putIfAbsent(String key, V value) {
        Objects.requireNonNull(key);
        V exists = this.get(key);
        if (exists == null) {
            return this.put(key, value);
        } else {
            return exists;
        }
    }

    @Override
    public V replace(String key, V value) {
        Objects.requireNonNull(key);
        return super.replace(key.toLowerCase(Locale.ROOT), value);
    }

    @Override
    public boolean replace(String key, V oldValue, V newValue) {
        Objects.requireNonNull(key);
        return super.replace(key.toLowerCase(Locale.ROOT), oldValue, newValue);
    }

    @Override
    public boolean remove(Object key, Object value) {
        Objects.requireNonNull(key);
        return super.remove(String.valueOf(key).toLowerCase(Locale.ROOT), value);
    }

    @Override
    public V remove(Object key) {
        Objects.requireNonNull(key);
        return super.remove(String.valueOf(key).toLowerCase(Locale.ROOT));
    }

    @Override
    public V merge(String key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
        Objects.requireNonNull(key);
        return super.merge(key.toLowerCase(Locale.ROOT), value, remappingFunction);
    }

    @Override
    public V getOrDefault(Object key, V defaultValue) {
        Objects.requireNonNull(key);
        return super.getOrDefault(String.valueOf(key).toLowerCase(Locale.ROOT), defaultValue);
    }

    @Override
    public V get(Object key) {
        Objects.requireNonNull(key);
        return super.get(String.valueOf(key).toLowerCase(Locale.ROOT));
    }

    @Override
    public V compute(String key, BiFunction<? super String, ? super V, ? extends V> remappingFunction) {
        Objects.requireNonNull(key);
        return super.compute(key.toLowerCase(Locale.ROOT), remappingFunction);
    }

    @Override
    public V computeIfAbsent(String key, Function<? super String, ? extends V> mappingFunction) {
        Objects.requireNonNull(key);
        return super.computeIfAbsent(key.toLowerCase(Locale.ROOT), mappingFunction);
    }

    @Override
    public V computeIfPresent(String key, BiFunction<? super String, ? super V, ? extends V> remappingFunction) {
        Objects.requireNonNull(key);
        return super.computeIfPresent(key.toLowerCase(Locale.ROOT), remappingFunction);
    }

    @Override
    public boolean containsKey(Object key) {
        Objects.requireNonNull(key);
        return super.containsKey(String.valueOf(key).toLowerCase(Locale.ROOT));
    }
}
